﻿#include "MdUserSpi.h"
#include "Tools.h"
#ifdef __linux__
#include <cstring>
#endif
#include "SymbolDetail.h"
#include "MarketTimeAmendment.h"
#include "MainSymbolGather.h"

CMdUserSpi::CMdUserSpi(MarketDataManager &marketManager) : m_marketManager(marketManager)
{
	m_frontConnectedFunc = nullptr;
	m_loginedFunc = nullptr;
	//m_unSubscribeFunc = nullptr;

	//// 将会注释掉
	//// 第一批K线的完成回调，要保存主力合约了
	//m_marketManager.SetTheFirstKItemsFinishedFeadBack([this]()->bool {
	//	saveMainSymbol();
	//	return true;
	//});
	//// 初始化上次的主力合约
	//initTheLastMainSymbol();

	// 行情时间纠正工具初始化
	MarketTimeAmendment::Instance();
	MainSymbolGather::Instance();
}

CMdUserSpi::~CMdUserSpi()
{
}

void CMdUserSpi::SetFrontConnectedFunc(std::function<void(void)> pFunc)
{
	m_frontConnectedFunc = pFunc;
}

void CMdUserSpi::SetLoginedFunc(std::function<void(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)> pFunc)
{
	m_loginedFunc = pFunc;
}

//void CMdUserSpi::SetUnSubscribeFunc(std::function<void(const std::list<std::string> &pList)> pFunc)
//{
//	m_unSubscribeFunc = pFunc;
//}
//
//void CMdUserSpi::GetVariableSymbolList(std::list<std::string> &outList)
//{
//	outList.clear();
//	// 首先尝试返回今天的主力合约列表
//	time_t curStamp = Tools::GetCurrentTimeStamp();
//	SymbolPackage::MainSymbolReaderWriter mainSymbols(Tools::GetDateTimeFrmStamp(curStamp));
//	mainSymbols.GetSymbolList(outList);
//	m_hasRecordMainSymbol = !outList.empty();
//	// 已有订单的合约也必须在监控中
//	SymbolPackage::OrderSymbolReaderWriter orderSymbols;
//	std::list<std::string> orderSymbolList;
//	orderSymbols.GetSymbolList(orderSymbolList);
//	for (std::list<std::string>::iterator it = orderSymbolList.begin(); it != orderSymbolList.end(); ++it)
//	{
//		m_orderSymbols.insert(*it);
//	}
//	outList.insert(outList.end(), orderSymbolList.begin(), orderSymbolList.end());
//	if (m_hasRecordMainSymbol)
//	{
//		return;
//	}
//
//	std::list<SymbolPackage::SymbolInfo> allSymbolInfoList;
//	SymbolPackage::GetTheLastFutureSymbolInfoList(allSymbolInfoList);
//
//	std::list<std::string> symbolNameList;
//	for (std::list<SymbolPackage::SymbolInfo>::iterator it = allSymbolInfoList.begin(); it != allSymbolInfoList.end(); ++it)
//	{
//		//std::string psymbol = it->InstrumentID;
//		//std::string symboltag = psymbol.substr(0, 2);
//		//if (symboltag.compare("cu") == 0)
//		{
//			symbolNameList.emplace_back(it->InstrumentID);
//		}
//	}
//	outList.swap(symbolNameList);
//}

void CMdUserSpi::OnFrontConnected()
{
	if (m_frontConnectedFunc != nullptr)
	{
		m_frontConnectedFunc();
	}
}

void CMdUserSpi::OnFrontDisconnected(int nReason)
{
	m_marketManager.SetCTPDisconnectTime(Tools::GetCurrentTimeStamp());
}

void CMdUserSpi::OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{
	if (m_loginedFunc != nullptr)
	{
		m_loginedFunc(pRspUserLogin, pRspInfo, nRequestID, bIsLast);
	}
	m_marketManager.ConnectedCTP();
}

void CMdUserSpi::OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{

}

void CMdUserSpi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{

}

void CMdUserSpi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{

}

void CMdUserSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData)
{
	if (pDepthMarketData == nullptr)
	{
		return;
	}
	if (pDepthMarketData->LastPrice > 1.7976931348623157e+30 || pDepthMarketData->LastPrice < 1.7976931348623157e-30)
	{ // 数据错误就直接返回
		return;
	}
	char tmpDay[9];
	tmpDay[0] = 0;
	if (MainSymbolGather::Instance().IsSHFEorINE(pDepthMarketData->InstrumentID))
	{
		strcpy(tmpDay, pDepthMarketData->ActionDay);
	}
	time_t curTmStamp = MarketTimeAmendment::Instance().GetRealTime(tmpDay, pDepthMarketData->UpdateTime);
	// 判断这个时间是否在行情段内，不在行情段内直接返回
	if (!MarketTimeAmendment::Instance().IsInCurSegment(curTmStamp))
	{
		return;
	}
	bool isMainSymbol = MainSymbolGather::Instance().IsMainSymbol(pDepthMarketData->InstrumentID, pDepthMarketData->OpenInterest, curTmStamp);
	if (!isMainSymbol)
	{
		return;
	}
	MData::PriceItem pItem;
	pItem.LastPrice = pDepthMarketData->LastPrice;
	pItem.UpdateTime = curTmStamp;
	pItem.UpdateMillisec = pDepthMarketData->UpdateMillisec;
	pItem.OpenInterest = pDepthMarketData->OpenInterest;
	pItem.Volume = pDepthMarketData->Volume;
	m_marketManager.UpdateMarket(pDepthMarketData->InstrumentID, pItem);
}

void CMdUserSpi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{

}

void CMdUserSpi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast)
{

}

void CMdUserSpi::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp)
{

}

//std::string CMdUserSpi::getClassName(TThostFtdcInstrumentIDType pSymbol)
//{
//	int len = strlen(pSymbol);
//	int classEndIndex = 0;
//	std::string pclassName;
//	for (int i = 0; i < len; ++i)
//	{
//		if (pSymbol[i] >= '0' && pSymbol[i] <= '9')
//		{
//			classEndIndex = i;
//			break;
//		}
//		pclassName.push_back(pSymbol[i]);
//	}
//	return pclassName;
//}
//
//void CMdUserSpi::saveMainSymbol()
//{
//	if (m_hasRecordMainSymbol) // 如果已经保存过主力合约了，那就直接返回就好了
//	{
//		return;
//	}
//	time_t curStamp = Tools::GetCurrentTimeStamp();
//	SymbolPackage::MainSymbolReaderWriter mainSymbols(Tools::GetDateTimeFrmStamp(curStamp));
//	for (std::map<std::string, std::pair<std::string, TThostFtdcLargeVolumeType>>::iterator it = m_mainSymbols.begin(); it != m_mainSymbols.end(); ++it)
//	{
//		mainSymbols.AppendSymbol(it->second.first);
//	}
//	mainSymbols.Save();
//	m_hasRecordMainSymbol = true;
//}
//
//void CMdUserSpi::initTheLastMainSymbol()
//{
//	std::list<std::string> symbolList;
//	SymbolPackage::GetTheLastMainSymbolList(symbolList, Tools::GetCurrentTimeStamp());
//	SymbolPackage::OrderSymbolReaderWriter orderSymbols;
//	orderSymbols.GetSymbolList(symbolList);
//
//	std::set<std::string> symbolsSet;
//	for (std::list<std::string>::iterator it = symbolList.begin(); it != symbolList.end(); ++it)
//	{
//		symbolsSet.insert(*it);
//	}
//	m_lastSymbolsSet.swap(symbolsSet);
//}
